/******************************************************
 Copyright (C) 2014 Yucheng Yao. All rights reserved.
 *******************************************************

 *******************************************************
 */
#ifndef CRYSTAL_FLOAT3_H
#define CRYSTAL_FLOAT3_H
#include <cmath>

namespace crystal {
	//vector with 3 floats.
	struct float3 {
		float x, y, z;

		float3(float x, float y, float z) :
				x(x), y(y), z(z) {
		}
		float3(const float3 &u) :
				x(u.x), y(u.y), z(u.z) {
		}
		float3() :
				x(0), y(0), z(0) {
		}

		float module() const;
		//ifloat3 normalization() const;
		void normalize();
	};

	/*************inline implementation for flaot3****************/
	inline float float3::module() const {
		return sqrtf(x * x + y * y + z * z);
	}
	inline void float3::normalize() {
		float m = module();
		x /= m;
		y /= m;
		z /= m;
	}
	inline float3 operator-(const float3 &u) {
		return float3(-u.x, -u.y, -u.z);
	}
	inline float3 operator+(const float3 &u, const float3 &v) {
		return float3(u.x + v.x, u.y + v.y, u.z + v.z);
	}
	inline float3 operator-(const float3 &u, const float3 &v) {
		return float3(-v + u);
	}
	inline float operator*(const float3 &u, const float3 &v) {
		return u.x * v.x + u.y * v.y + u.z * v.z;
	}
	inline float3 operator*(const float &a, const float3 &u) {
		return float3(a * u.x, a * u.y, a * u.z);
	}
	inline float3 operator*(const float3 &u, const float &a) {
		return a * u;
	}
	inline float3 operator/(const float3 &u, const float &a) {
		return 1.0f / a * u;
	}
}

#endif
